package thu.infinity.commons;

public abstract class Task implements Runnable, Comparable<Task> {
	protected static int count = 0;
	protected int id;
	protected AggregatorHandler handler;
	protected TaskScheduler scheduler;
	protected long creatTime;
	protected long expireTime;
	protected long period;
	protected boolean isPeriodical;
	protected boolean futureRemovable;
	
	public long getExpireTime() {
		return expireTime;
	}
	
	public int getId() {
		return id;
	}

	public TaskScheduler getScheduler() {
		return scheduler;
	}

	public long getCreatTime() {
		return creatTime;
	}	
	
	public long getPeriod() {
		return period;
	}
	
	public boolean getFutureRemovable() {
		return futureRemovable;
	}

	public void setFutureRemovable(boolean futureRemovable) {
		this.futureRemovable = futureRemovable;
	}
	public void setScheduler(TaskScheduler scheduler) {
		this.scheduler = scheduler;
	}
	
	public void setPeriod(long period) {
		this.period = period;
	}
	
	public void setExpireTime(long expireTime) {	
		this.expireTime = expireTime;
	}

	public Task() {
		creatTime = System.currentTimeMillis();
		futureRemovable = true;
		this.expireTime = 0; // for instant task
		this.id = count++;
	}
	
	public Task(long expireTime) {		
		creatTime = System.currentTimeMillis();
		futureRemovable = true;
		this.expireTime = expireTime;
		this.id = count++;
	}
	
	public Task(long expireTime, long period) {
		this.expireTime = expireTime;
		futureRemovable = true;
		this.id = count++;
		this.period = period;		
	}
		
	public abstract void execute();
	
	public abstract boolean checkCondition();
	
	protected abstract Task genNextTask();
	
	@Override
	public void run() {
		//System.out.println("Task run.");
		if (isPeriodical && scheduler != null) {
			System.out.println("Periodical");
			scheduler.AddTask(genNextTask());
		}
		if (checkCondition()) {
			//System.out.println("execute");
			execute();
		}
	}
	
	@Override
	public int compareTo(Task task) {
		return (int) (this.id - task.getId());
	}
}
